#ifndef __CM_NAT_MULTICAST_PORT_H__
#define __CM_NAT_MULTICAST_PORT_H__

#include "Port.h"
#include "cm_base/ByteBuffer.h"
#include "cm_base/ByteBufferPool.h"

#include "Poco/Thread.h"
#include "Poco/Runnable.h"
#include "Poco/Net/MulticastSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/Net/SocketReactor.h"

using Poco::Runnable;
using Poco::Thread;
using Poco::Net::Socket;
using Poco::Net::MulticastSocket;
using Poco::Net::SocketAddress;
using Poco::Net::SocketReactor;
using Poco::Net::IPAddress;
using namespace cm_base;

namespace cm_nat
{
    class MulticastPort;

    class MulticastPortListener
    {
    public:
        virtual void onReceive(MulticastPort*p_port, ByteBuffer* p_data) =0;

    };

    class MulticastPort: public Port, public Runnable 
    {
    public:
        MulticastPort(SocketReactor& reactor,ByteBufferPool* pool);
        virtual ~MulticastPort();

        int setup(int type, IPAddress bindIP, SocketAddress groupAddress);
        int teardown();

        void registerListener( MulticastPortListener* p_listener );

        SocketAddress& getBindAddress();

        //from class Port
        int send(ByteBuffer* p_data,const SocketAddress& sa);
        void onReceive( ReadableNotification * p_rn);
        //from class Runnable
        void run();

        enum{
            EVENT_RECVED_DATA ,
            EVENT_TO_SEND_DATA 
        };
        enum{
            MULTICAST_SERVER,
            MULTICAST_CLIENT
        };


    protected:
        MulticastSocket m_socket;

        NotificationQueue m_queue;

        ByteBufferPool* m_buffer_pool;

        SocketAddress m_groupAddress;

        SocketAddress m_bindAddress;
        
        SocketReactor& m_reactor;

        Thread m_thread;
        bool m_stop;

        MulticastPortListener* m_listener;
    };

}


#endif